import com.alibaba.fastjson.JSON;
import com.coderknock.jedis.KeyGen;
import com.coderknock.jedis.executor.JedisExecutor;
import com.coderknock.service.TopService;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.TestInstance;
import redis.clients.jedis.Tuple;

import java.io.IOException;
import java.time.LocalDateTime;
import java.time.temporal.ChronoUnit;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import java.util.logging.Logger;

import static org.junit.jupiter.api.Assertions.assertEquals;

/**
 * <p></p>
 *
 * @author mouliu
 * @version 1.0
 * @date 2017-09-02
 * @since JDK 1.8
 */
@DisplayName("提升职业竞争力的必备知识 Redis 排行榜 Demo")
@TestInstance(TestInstance.Lifecycle.PER_CLASS)
public class TopDemo {
    static final Logger LOG = Logger.getLogger(TopDemo.class.getName());

    private TopService topService = new TopService();
    private Map<String, Map<String, Double>> tagMapper = new HashMap<>();

    /**
     * 执行命令前清空数据库，并初始化相关数据
     */
    @BeforeAll
    public void initData() {
          JedisExecutor.executeNR(jedis -> jedis.flushAll());
          LOG.info("清空 Redis 中的数据");
        Map<String, Double> javaTagScoreMembers = new HashMap<>();
        javaTagScoreMembers.put("有明", 3269d);
        javaTagScoreMembers.put("边城", 3268d);
        javaTagScoreMembers.put("kevinz", 2994d);
        javaTagScoreMembers.put("justjavac", 2918d);
        javaTagScoreMembers.put("mouliu", 1024d);
        tagMapper.put("Java", javaTagScoreMembers);
        Map<String, Double> pythonScoreMembers = new HashMap<>();
        pythonScoreMembers.put("prolifes", 6689d);
        pythonScoreMembers.put("依云", 6038d);
        pythonScoreMembers.put("hsfzxjy", 4895d);
        pythonScoreMembers.put(" dokelung", 3881d);
        pythonScoreMembers.put("mouliu", 1024d);
        tagMapper.put("Python", pythonScoreMembers);
        Map<String, Double> redisScoreMembers = new HashMap<>();
        redisScoreMembers.put("Mr_Jing", 1030d);
        redisScoreMembers.put("joyqi", 884d);
        redisScoreMembers.put("beanlam", 508d);
        redisScoreMembers.put("有明", 416d);
        redisScoreMembers.put("mouliu", 343d);
        tagMapper.put("Redis", redisScoreMembers);
        Map<String, Double> kotlinScoreMembers = new HashMap<>();
        kotlinScoreMembers.put("wishing", 101d);
        kotlinScoreMembers.put("Gemini", 77d);
        kotlinScoreMembers.put("sorra", 47d);
        kotlinScoreMembers.put("之剑", 35d);
        kotlinScoreMembers.put("mouliu", 26d);
        tagMapper.put("Kotlin", kotlinScoreMembers);
        //循环初始化标签
        tagMapper.forEach((key, scoreMembers) -> {
            Long tagResul = topService.tagInit(key, scoreMembers);
            //断言判断添加是否成功
            assertEquals(Long.valueOf(scoreMembers.size()), tagResul);
        });
    }

    @DisplayName("排行榜")
    @Test
    public void top() throws IOException {
        long start = 0l;
        long end = 9l;
        //获取
        tagMapper.forEach((key, scoreMembers) -> topService.tagTop(key, start, end));
        String[] tags = tagMapper.keySet().toArray(new String[]{});
        // 查询所标签的集合（同一个人的积分会叠加）的排行榜
        topService.tagsTop(start, end, tags);
        topService.incrTag("Java", "mouliu", 888d);
        topService.tagsTop(start, end, tags);
        topService.incrTag("Python", "mouliu", 999d);
        topService.tagTop("Java", start, end);
        topService.tagTop("Python", start, end);
        topService.tagsTop(start, end, tags);
    }


    @DisplayName("今日排行")
    @Test
    public void topToday() throws IOException {
        topService.incrTag("Java", "mouliu", 888d);
        topService.incrTag("Java", "mouliu", 888d);
        topService.incrTag("运营", "keke", 666d);
        topService.incrTag("SF", "清蒸", 999d);
        LocalDateTime time = LocalDateTime.now();
        LocalDateTime dateTime = time.plus(8, ChronoUnit.DAYS);

        topService.incrTag("SF", "清蒸", 999d, dateTime);

        long start = 0l;
        long end = 9l;
        topService.todayTop(start, end);
    }

    @DisplayName("月排行")
    @Test
    public void mouthTop() throws IOException {
        LocalDateTime time = LocalDateTime.now();
        String key = KeyGen.MONTH_TOP_SCORE.genDateKey(time);
        String tagMouthKey = KeyGen.TAG_TOP_SCORE.genKeyWithDate("Java", time);
        LOG.info(key);
        //1、针对标签的月的排行
        Set<Tuple> set = JedisExecutor.execute(jedis -> jedis.zrevrangeWithScores(tagMouthKey, 0, 2));
        LOG.info("Java");
        set.forEach(ele -> {
            LOG.info(ele.getElement() + "--->" + ele.getScore());
        });
        //2、总的月排行
        LOG.info("总榜");
        set = JedisExecutor.execute(jedis -> jedis.zrevrangeWithScores(key, 0, 2));
        set.forEach(ele -> {
            LOG.info(ele.getElement() + "--->" + ele.getScore());
        });
    }


    @Test
    public void test() {
        Set<String> stringSet = JedisExecutor.execute(jedis -> jedis.keys("*"));
        System.out.println(JSON.toJSONString(stringSet));
    }
}
